
package com.ru.application.creditscore.domain;

import static javax.persistence.CascadeType.PERSIST;
import static javax.persistence.FetchType.LAZY;
import static org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.apache.log4j.Logger;
import org.hibernate.annotations.Cache;
import com.google.common.base.Objects;
import com.ru.application.creditscore.domain.IdentifiableHashBuilder;
import com.ru.application.creditscore.domain.ScoringRule;
import com.ru.application.creditscore.validation.FixedLength;

@Entity
@Table(name = "SCORING_RULE_CASE")
@Cache(usage = NONSTRICT_READ_WRITE)
public class ScoringRuleCase implements Identifiable<Integer>, Serializable {
    private static final long serialVersionUID = 1L;
    private static final Logger log = Logger.getLogger(ScoringRuleCase.class);

    // Raw attributes
    private Integer id; // pk
    private String factorChoice;
    private Integer score;

    // Technical attributes for query by example
    private Integer ruleId;

    // Many to one
    private ScoringRule rule; // (ruleId)

    // ---------------------------
    // Constructors
    // ---------------------------

    public ScoringRuleCase() {
    }

    public ScoringRuleCase(Integer primaryKey) {
        setId(primaryKey);
    }

    // -------------------------------
    // Getter & Setter
    // -------------------------------

    // -- [id] ------------------------

    @Column(name = "id", precision = 10)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="scoring_rule_case_id_seq")
    @SequenceGenerator(name="scoring_rule_case_id_seq", sequenceName="scoring_rule_case_id_seq",allocationSize=1)
    @Id
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Transient
    public boolean isIdSet() {
        return id != null;
    }

    // -- [factorChoice] ------------------------

    //@FixedLength(length = 255)
    @Column(name = "factor_choice", length = 255)
    public String getFactorChoice() {
        return factorChoice;
    }

    public void setFactorChoice(String factorChoice) {
        this.factorChoice = factorChoice;
    }

    // -- [ruleId] ------------------------

    @Column(name = "rule_id", precision = 10, insertable = false, updatable = false)
    public Integer getRuleId() {
        return ruleId;
    }

    private void setRuleId(Integer ruleId) {
        this.ruleId = ruleId;
    }

    // -- [score] ------------------------

    @Column(name = "score", precision = 10)
    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    // --------------------------------------------------------------------
    // Many to One support
    // --------------------------------------------------------------------

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // many-to-one: ScoringRuleCase.ruleId ==> ScoringRule.id
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    @Cache(usage = NONSTRICT_READ_WRITE)
    @JoinColumn(name = "rule_id")
    @ManyToOne(cascade = PERSIST, fetch = LAZY)
    public ScoringRule getRule() {
        return rule;
    }

    /**
     * Set the rule without adding this ScoringRuleCase instance on the passed rule
     * If you want to preserve referential integrity we recommend to use
     * instead the corresponding adder method provided by {@link ScoringRule}
     */
    public void setRule(ScoringRule rule) {
        this.rule = rule;

        // We set the foreign key property so it can be used by our JPA search by Example facility.
        if (rule != null) {
            setRuleId(rule.getId());
        } else {
            setRuleId(null);
        }
    }

    /**
     * Set the default values.
     */
    public void initDefaultValues() {
    }

    /**
     * equals implementation using a business key.
     */
    @Override
    public boolean equals(Object other) {
        return this == other || (other instanceof ScoringRuleCase && hashCode() == other.hashCode());
    }

    private IdentifiableHashBuilder identifiableHashBuilder = new IdentifiableHashBuilder();

    @Override
    public int hashCode() {
        return identifiableHashBuilder.hash(log, this);
    }

    /**
     * Construct a readable string representation for this ScoringRuleCase instance.
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return Objects.toStringHelper(this) //
                .add("id", getId()) //
                .add("factorChoice", getFactorChoice()) //
                .add("ruleId", getRuleId()) //
                .add("score", getScore()) //
                .toString();
    }

}